package com.zj.dmsproxy.interfaces.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.zj.baseproxy.enums.TypeEnum;
import com.zj.baseproxy.interfaces.HttpHandler;
import com.zj.baseproxy.model.Page;
import com.zj.dmsproxy.interfaces.DmsProxy;
import com.zj.dmsproxy.model.DmsInfo;
import com.zj.dmsproxy.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author arthur_zhou
 */
@Slf4j
public class DmsProxyImpl implements DmsProxy {

    private static final String SUCCESS = "1";

    @Resource
    private HttpHandler httpHandler;

    @Override
    public <T> Page<T> getData(Class<T> clazz, DmsInfo dmsInfo, String json) {
        if (Objects.isNull(clazz)) {
            return Page.setPageData();
        }
        JSONObject jsonObject = requestDms(dmsInfo, json);
        //无数据存在直接返回结果
        if (Objects.isNull(jsonObject)) {
            return Page.setPageData();
        }
        JSONArray jsonArray = getDataList(jsonObject);
        Long total = getTotal(jsonObject);
        List<T> responseList = jsonArray.stream()
                .filter(Objects::nonNull)
                .map(v -> JsonUtil.cast(v, clazz))
                .collect(Collectors.toList());
        return Page.setPageData(responseList, total);
    }

    @Override
    public JSONObject getJsonData(DmsInfo dmsInfo, String json) {

        JSONObject jsonObject = requestDms(dmsInfo, json);
        //无数据存在直接返回结果
        if (Objects.isNull(jsonObject)) {
            return new JSONObject();
        }
        return jsonObject;
    }

    @Override
    public <T> Page<T> map(DmsInfo dmsInfo, String json, Function<JSONObject, T> func) {

        JSONObject jsonObject = requestDms(dmsInfo, json);
        //无数据存在直接返回结果
        if (Objects.isNull(jsonObject)) {
            return Page.setPageData(Collections.emptyList(), 0L);
        }
        JSONArray jsonArray = getDataList(jsonObject);
        Long total = getTotal(jsonObject);
        // 收集遍历后的数据
        List<T> resultList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            T result = func.apply(object);
            resultList.add(result);
        }
        return Page.setPageData(resultList, total);
    }

    @Override
    public Long foreach(DmsInfo dmsInfo, String json, Consumer<JSONObject> consumer) {

        JSONObject jsonObject = requestDms(dmsInfo, json);
        //无数据存在直接返回结果
        if (Objects.isNull(jsonObject)) {
            return 0L;
        }
        JSONArray jsonArray = getDataList(jsonObject);
        Long total = getTotal(jsonObject);
        // 收集遍历后的数据
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            consumer.accept(object);
        }
        return total;
    }

    /**
     * 请求dms
     *
     * @param dmsInfo dms信息
     * @param json    json
     * @return 请求返回数据
     */
    private JSONObject requestDms(DmsInfo dmsInfo, String json) {
        if (StringUtils.isEmpty(dmsInfo.getRealUrl())) {
            log.error("缺少路径信息");
            return null;
        }
        String responseJson = httpHandler.post(TypeEnum.DMS, dmsInfo.getRealUrl(), json);
        // 校验数据
        JSONObject jsonObject = checkStatusIsSuccess(responseJson);
        if (Objects.isNull(jsonObject)) {
            return null;
        }
        JSONArray jsonArray = getDataList(jsonObject);
        Long total = getTotal(jsonObject);
        // 如果查询了总数且为0
        if (Objects.nonNull(total) && total == 0L) {
            return null;
        }
        // 无数据存在放入空数组
        if (CollectionUtil.isEmpty(jsonArray)) {
            jsonObject.put("list", Collections.emptyList());
        }
        return jsonObject;
    }

    /**
     * 校验返回json
     *
     * @param json json
     * @return json里的data字段数据
     */
    private JSONObject checkStatusIsSuccess(String json) {
        if (StringUtils.isEmpty(json)
                || !JSONValidator.Type.Object.equals(JSONValidator.from(json).getType())) {
            log.error("dms响应解析错误：{}", json);
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (CollectionUtil.isEmpty(jsonObject)) {
            return null;
        }
        String status = jsonObject.getString("status");
        if (!SUCCESS.equalsIgnoreCase(status)) {
            log.error("dms调用错误：{}", jsonObject);
            return null;
        }
        String dataStr = jsonObject.getString("data");
        if (StringUtils.isEmpty(dataStr)
                || !JSONValidator.Type.Object.equals(JSONValidator.from(dataStr).getType())) {
            log.error("dms响应错误：{}", json);
            return null;
        }
        return jsonObject.getJSONObject("data");
    }

    /**
     * 获取数据列表
     *
     * @param jsonObject 响应
     * @return 数据列表
     */
    private JSONArray getDataList(JSONObject jsonObject) {
        return jsonObject.getJSONArray("list");
    }

    /**
     * 获取总数
     *
     * @param jsonObject 响应
     * @return 总数
     */
    private Long getTotal(JSONObject jsonObject) {
        return jsonObject.getLong("total");
    }

}
